﻿using UnityEngine;
using System.Collections.Generic;
using Framework.AssetsManager;

public enum SoundStyle
{
    allSound,
    music
}
public class SoundManager
{
    #region singleton
    static SoundManager _instance;

    public static SoundManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new SoundManager();
            }
            return _instance;
        }
    }

    #endregion
    public float AllSoundVolume
    {
        get
        {
            if (PlayerPrefs.HasKey("AllSoundVolume"))
                return PlayerPrefs.GetFloat("AllSoundVolume");
            else
                return 1f;
        }

        set
        {
            PlayerPrefs.SetFloat("AllSoundVolume", value);
            PlayerPrefs.Save();
        }
    }

    public float MusicVolume
    {
        get
        {
            if (PlayerPrefs.HasKey("MusicVolume"))
                return PlayerPrefs.GetFloat("MusicVolume");
            else
                return 1f;
        }

        set
        {
            PlayerPrefs.SetFloat("MusicVolume", value);
            PlayerPrefs.Save();
        }
    }

    Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>();

    List<AudioSource> AllSounds = new List<AudioSource>();
    List<AudioSource> MusicSounds = new List<AudioSource>();
    public void Clear()
    {
        AllSounds.Clear();
        MusicSounds.Clear();
    }

    public void SetVolume(SoundStyle type,float value, bool isTemporary = false)
    {
        if (type == SoundStyle.allSound)
        {
            if(!isTemporary)
                AllSoundVolume = value;
            float musicVolume = value * MusicVolume;
            for(int i = AllSounds.Count - 1; i >= 0; i--)
            {
                AudioSource child = AllSounds[i];
                if (child != null)
                    child.volume = value;
                else
                    AllSounds.RemoveAt(i);
            }

            for (int i = MusicSounds.Count - 1; i >= 0; i--)
            {
                AudioSource child = MusicSounds[i];
                if (child != null)
                    child.volume = musicVolume;
                else
                    MusicSounds.RemoveAt(i);
            }
        }
        else
        {
            if(!isTemporary)
                MusicVolume = value;
            float musicVolume = value * AllSoundVolume;
            for (int i = MusicSounds.Count - 1; i >= 0; i--)
            {
                AudioSource child = MusicSounds[i];
                if (child != null)
                {
                    child.volume = musicVolume;
                }
                else
                    MusicSounds.RemoveAt(i);
            }
        }
    }

    public AudioSource PlayOnce(string name, bool is3D, Vector3 pos, SoundStyle type= SoundStyle.allSound)
    {
        if (audioClips.ContainsKey(name) == false)
            audioClips[name] = RM.Instance.GetResource("Sound/" + name) as AudioClip;
        AudioClip clip = audioClips[name];
        GameObject soundSource = null;
        if (is3D)
            soundSource = GameObject.Instantiate(RM.Instance.GetResource("Prefab/Sound/Audio3D")) as GameObject;
        else
            soundSource = GameObject.Instantiate(RM.Instance.GetResource("Prefab/Sound/BGM")) as GameObject;
       // soundSource.transform.parent = parent;
        soundSource.transform.localPosition = pos;
        AudioSource audio = soundSource.GetComponent<AudioSource>();
        audio.loop = false;
        audio.volume = (!is3D) ? AllSoundVolume : MusicVolume* AllSoundVolume;
        audio.clip = clip;
        audio.Play();

        GameObject.Destroy(soundSource, clip.length);
        return audio;
    }

    public AudioSource PlayLoop(string name, bool is3D, Transform parent = null,SoundStyle type= SoundStyle.allSound)
    {
        if (audioClips.ContainsKey(name) == false)
            audioClips[name] = RM.Instance.GetResource("Sound/" + name) as AudioClip;
        AudioClip clip = audioClips[name];
        GameObject soundSource = null;
        if (is3D)
            soundSource = GameObject.Instantiate(RM.Instance.GetResource("Prefab/Sound/Audio3D")) as GameObject;
        else
            soundSource = GameObject.Instantiate(RM.Instance.GetResource("Prefab/Sound/BGM")) as GameObject;
        soundSource.transform.SetParent(parent);
        AudioSource audio = soundSource.GetComponent<AudioSource>();
        if (type == SoundStyle.allSound)
            AllSounds.Add(audio);
        else
            MusicSounds.Add(audio);
        audio.loop = true;
        audio.clip = clip;
        audio.volume = (!is3D) ? AllSoundVolume : MusicVolume * AllSoundVolume;
        audio.Play();
        return audio;
    }

    public void StopLoop(AudioSource source)
    {
        AllSounds.Remove(source);
        MusicSounds.Remove(source);
        if(source.gameObject != null)
            GameObject.Destroy(source.gameObject);
    }
}
